import 'dart:convert';

import 'package:bxultimate/data/store/auth_store.dart';
import 'package:bxultimate/data/store/im_store.dart';
import 'package:bxultimate/widgets/webrtc/rtc_util.dart';
import 'package:bxultimate/widgets/webrtc/webrtc_api.dart';
import 'package:flutter/foundation.dart';
import 'package:get/get.dart' hide navigator;
import 'state.dart';
import 'dart:core';
import 'package:flutter_ringtone_player/flutter_ringtone_player.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart';

class VideoChatController extends GetxController {
  final VideoChatState state = VideoChatState();
  WebRtcController webRtcController = Get.put(WebRtcController());
  MediaStream? _localStream;
  late RTCVideoRenderer localRenderer = RTCVideoRenderer();
  late RTCVideoRenderer remoteRenderer = RTCVideoRenderer();
  List<RTCRtpSender> senders = <RTCRtpSender>[];
  List<MediaDeviceInfo>? _mediaDevicesList;
  RTCPeerConnection? localPc;
  RTCPeerConnection? pc2;
  final roomId = Get.arguments['roomId'];
  final userId = Get.arguments['userId'];
  final userName = Get.arguments['userName'];
  final ownUrl = Get.arguments['ownUrl'];

  @override
  Future<void> onInit() async {
    // TODO: implement onInit

    super.onInit();

    await localRenderer.initialize();

    final mediaConstraints = <String, dynamic>{
      'audio': true,
      'video': {
        'mandatory': {
          'minWidth':
              '640', // Provide your own width, height and frame rate here
          'minHeight': '480',
          'minFrameRate': '30',
        },
        'facingMode': 'user',
        'optional': [],
      }
    };

    var stream = await navigator.mediaDevices.getUserMedia(mediaConstraints);
    _mediaDevicesList = await navigator.mediaDevices.enumerateDevices();
    _localStream = stream;
    localRenderer.srcObject = _localStream;

    // 申请 摄像头和 麦克风权限
    webRtcController.loadDevices();
    navigator.mediaDevices.ondevicechange = (event) {
      webRtcController.loadDevices();
    };

  }

  void accept() {
    FlutterRingtonePlayer.stop();

    addRemoteLive('webrtc://srs.sxbdjw.com/live/testMy');

    ImStore.getInstance().publishMessage(
        '${userId}_web',
        json.encode({
          'event': 'in_room',
          'roomId': roomId,
          'userId': AuthStore.to.profile.id,
          'type': 'video',
          'userName': AuthStore.to.profile.username,
        }));

    initLocal();
    state.isAccept = true;
    update();
  }

  void reject() {
    FlutterRingtonePlayer.stop();

    // 发送拒绝消息
    ImStore.getInstance().publishMessage(
        '${userId}_web',
        json.encode({
          'event': 'user_refuse',
          'roomId': roomId,
          'userId': AuthStore.to.profile.id,
          'userName': AuthStore.to.profile.username,
        }));

    Get.back();
  }

  initLocal() async {
    try {
      localPc = await createPeerConnection({
        'sdpSemantics': 'unified-plan',
      });

      _localStream?.getTracks().forEach((MediaStreamTrack track) async {
        var rtpSender = await localPc!.addTrack(track, _localStream!);
        senders.add(rtpSender);
      });

      /// 进行 webrtc  握手
      var offer = await localPc!.createOffer();
      await localPc!.setLocalDescription(offer);
      var answer = await webRtcHandshake(
          'webrtc://srs.sxbdjw.com/1312312', offer.sdp ?? '',
          type: 'publish');
      // 设置 本地推流的 远程描述  为 远程的 answer
      await localPc!.setRemoteDescription(answer);
      update();
    } catch (e) {
      print(e.toString());
    }
  }

  /// 添加远程视频
  addRemoteLive(String url) async {
    try {
      remoteRenderer = RTCVideoRenderer();
      await remoteRenderer.initialize();

      // 设置本地描述
      pc2 = await createPeerConnection({'sdpSemantics': "unified-plan"});
      var offer = await pc2!.createOffer({
        'mandatory': {'OfferToReceiveAudio': true, 'OfferToReceiveVideo': true},
      });
      await pc2!.setLocalDescription(offer);
      pc2!.onTrack = (event) {
        if (event.track.kind == 'video') {
          pc2!.addTrack(event.track, event.streams[0]);
          remoteRenderer.srcObject = event.streams[0];
        }
      };

      await pc2!.addTransceiver(
        kind: RTCRtpMediaType.RTCRtpMediaTypeAudio,
        init: RTCRtpTransceiverInit(direction: TransceiverDirection.RecvOnly),
      );
      await pc2!.addTransceiver(
        kind: RTCRtpMediaType.RTCRtpMediaTypeVideo,
        init: RTCRtpTransceiverInit(direction: TransceiverDirection.RecvOnly),
      );

      // 获取拉流视频的远程 answer 描述
      var answer = await webRtcHandshake(url, offer.sdp ?? '');
      await pc2!.setRemoteDescription(answer);
    } catch (e) {
      print('webrtc - 添加远程视频失败$e');
    }
  }

  @override
  void onClose() async {
    // TODO: implement onClose
    super.onClose();
    if (kIsWeb) {
      _localStream?.getTracks().forEach((track) => track.stop());
    }
    if (localPc != null) {
      await localPc!.close();
    }
    if (pc2 != null) {
      await pc2!.close();
    }

    try {
      localRenderer.srcObject = null;
      remoteRenderer.srcObject = null;
    } catch (e) {}
    await localRenderer.dispose();
    await remoteRenderer.dispose();
  }

  void close() {
    FlutterRingtonePlayer.stop();

    // 发送拒绝消息
    ImStore.getInstance().publishMessage(
        '${userId}_web',
        json.encode({
          'event': 'out_room',
          'roomId': roomId,
          'userId': AuthStore.to.profile.id,
          'userName': AuthStore.to.profile.username,
        }));
    Get.back();
  }

  void rotateVideo() async {
    final videoTrack = _localStream!
        .getVideoTracks()
        .firstWhere((track) => track.kind == 'video');
    await Helper.switchCamera(videoTrack);
  }

  void switchOutput() async {
    _mediaDevicesList!
        .where((device) => device.kind == 'audiooutput')
        .map((device) {});
  }
}
